/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#pragma once

#include <vector>
#include "../shared/geom.h"

// List of Vectors
typedef std::vector<Vector2f> type_VectorList;

/**
=================================
A physics object is anything that moves and/or
needs updating of physical orientation
=================================
*/
class PhysicsObject
{
public:
    PhysicsObject(void);

    /** Update this object */
    void Update( float deltaTime );

    /** Get/Set the mass */
    void SetMass( float mass ) { m_fMass = mass; };
    float GetMass() const { return m_fMass; };

    /** Get/Set the friction */
    void SetFriction( float friction ) { m_fFriction = friction; };
    float GetFriction() const { return m_fFriction; };

    /** Get/Set Velocity */
    void SetVelocity( const Vector2f &v ) { m_vVelocity = v; };
    Vector2f GetVelocity() const { return m_vVelocity; };

    /** Get/Set Position */
    void SetPosition( const Vector2f &v ) { m_vPosition = v; };
    Vector2f GetPosition() const { return m_vPosition; };

    /** Get/Set Acceleration */
    void SetAcceleration( const Vector2f &v ) { m_vAcceleration = v; };
    Vector2f GetAcceleration() const { return m_vAcceleration; };

    /** Get/Set a Destination */
    void SetDestination( const Vector2f &v ) { m_vDestination = v; };
    Vector2f GetDestination() { return m_vDestination; };

    /** Add a force to this object */
    void ApplyForce( const Vector2f &f ) { m_forces.push_back( f ); };
    /** Add an impulse ( an impulse is a force only applied once in an update ) */
    void ApplyImpulse(const Vector2f &f ) { m_impulses.push_back( f ); };
private:
    // Mass of object
    float   m_fMass;
    // Friction
    float   m_fFriction;
    // Velocity 
    Vector2f m_vVelocity;
    // Position
    Vector2f m_vPosition;
    // Acceleration
    Vector2f m_vAcceleration;
    // Destination
    Vector2f m_vDestination;

    // constant forces applied to this object
    type_VectorList     m_forces;
    // impulses applied - such as fake gravity
    type_VectorList     m_impulses;

public:
    virtual ~PhysicsObject(void);
};


/**
================================
Linear Interpolation Method
================================
*/
class LinearInterpolation
{
public:
    LinearInterpolation();

    /** Initialize */
    void Init( const Vector2f &startPosition, float totalTime );
    /** Update */
    void Update( float deltaTime );

    /** Get the current position */
    Vector2f    GetPosition() { return m_vPosition; };
private:
    // total time in ms
    float   m_fEndTimeMSec;
    // time passed
    float   m_fTimePassed;
    // current Position
    Vector2f    m_vPosition;

};